package cc.linker.steplink.crm.task;

import cc.linker.steplink.crm.commons.http.HttpService;
import cc.linker.steplink.crm.commons.lock.RedisLock;
import cc.linker.steplink.crm.response.GlobalException;
import cc.linker.steplink.crm.service.CustomerService;
import cc.linker.steplink.crm.service.IMarketRobotService;
import cc.linker.steplink.crm.service.ISysConfig;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mongodb.util.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.*;

@Slf4j
@Component
public class SendWxMessageTask {

    @Value("${system.scrm.wxpushurl}")
    private String url;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private HttpService httpService;

    @Autowired
    private IMarketRobotService marketRobotService;

    @Autowired
    private ISysConfig sysConfigService;

    @Autowired
    private CustomerService customerService;

    @Value("wxpushlist_lock")
    private String wxPushListLockKey;//队列锁键值

    @Value("wxpushlist")
    private String wxPushListKey;//队列键值

    /**
     * 发送客服消息
     * @throws IOException
     * @throws URISyntaxException
     * @throws GlobalException
     */
    @RedisLock("SendWxMessage_SendActiveMsg")
    @Scheduled(cron = "10 */10 * * * ?")
    public void SendActiveMsg() throws IOException, URISyntaxException, GlobalException {

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        Date expireDate = calendar.getTime();

        Calendar calendarToday = Calendar.getInstance();
        calendarToday.set(Calendar.HOUR_OF_DAY, 23);
        calendarToday.set(Calendar.MINUTE, 59);
        calendarToday.set(Calendar.SECOND, 59);
        Date today = calendarToday.getTime();

        Set<String> members = stringRedisTemplate.opsForSet().members(wxPushListKey);
        if(null == members || members.size()==0){
            //System.out.println("没任务要推送");
            return;
        }
        long nowtime = new Date().getTime() / 1000;
        out:for (String str:members){
            Map ret = (Map) JSON.parse(str);
            String[] condition = {"token","openid","image","time","title","url","desc","articleId","type"};
            for (String s : condition) {
                if (StringUtils.isEmpty(ret.get(s))){
                    stringRedisTemplate.opsForSet().remove(wxPushListKey, str);
                    continue out;
                }
            }
            //时间没到，不发
            if(Long.parseLong(ret.get("time").toString())>nowtime){
                continue;
            }
            Map<String, String> pushdata = new HashMap<>();
            pushdata.put("action", "replayNews");
            pushdata.put("title", ret.get("title").toString());
            pushdata.put("desc", ret.get("desc").toString());
            pushdata.put("url", ret.get("url").toString());
            pushdata.put("image", ret.get("image").toString());
            pushdata.put("token", ret.get("token").toString());
            pushdata.put("openid", ret.get("openid").toString());

            Map<String, String> postParam = new HashMap<>();
            postParam.put("Content-Type", "application/json;charset=UTF-8");

            JSONObject jsonObject = (JSONObject) JSONArray.toJSON(pushdata);
            Object postresJson = httpService.doPost(url,jsonObject.toJSONString(),postParam);

            String lockValue = ret.get("token").toString()+ret.get("openid").toString();

            Map postres  = (Map)JSON.parse(postresJson.toString());
            if(null!=postres){
                pushdata.put("type",ret.get("type").toString());
                pushdata.put("articleId",ret.get("articleId").toString());

                //移除
                stringRedisTemplate.opsForSet().remove(wxPushListLockKey,lockValue);

                String touchcountKey = "touchcount_"+ret.get("orgId").toString()+ret.get("type").toString();
                String alltouchcountKey = "alltouchcount_"+ret.get("orgId").toString()+ret.get("type").toString();

                if("200".equals(postres.get("errcode").toString())){
                    //触达人数+1
                    stringRedisTemplate.opsForSet().add(alltouchcountKey,lockValue);
                    stringRedisTemplate.opsForSet().add(touchcountKey,lockValue);
                    stringRedisTemplate.expireAt(touchcountKey,today);
                    //stringRedisTemplate.opsForValue().increment(touchcountKey,1);
                    pushdata.put("status","1");
                }else{
                    pushdata.put("status","0");
                    //发送失败后，把数据按照文章id分类----再根据文章id创建一个set
                    String massKey = "textMassMessageList_"+ret.get("articleId").toString();
                    Map<String, String> massData = new HashMap<>();
                    massData.put("articleId",ret.get("articleId").toString());
                    massData.put("url",ret.get("url").toString());
                    massData.put("title",ret.get("title").toString());
                    massData.put("token",ret.get("token").toString());
                    massData.put("openid",ret.get("openid").toString());
                    massData.put("orgId",ret.get("orgId").toString());
                    massData.put("type",ret.get("type").toString());
                    stringRedisTemplate.opsForSet().add(massKey, JSON.serialize(massData));
                    stringRedisTemplate.expireAt(wxPushListKey,expireDate);
                }
                marketRobotService.savePushLog(pushdata);

                //添加动态
                Map<String, String> tmpParam = new HashMap<>();
                Integer customerCount = customerService.getCustomerCountByOrgId(ret.get("orgId").toString());


                //获取机器人配置
                Integer limitNum = 0;
                Map<String, Object> orgFunction = customerService.getOrgFunctionOrgId((String)ret.get("orgId"));
                if("market".equals(ret.get("type").toString())){
                    if(null!=orgFunction && !StringUtils.isEmpty(orgFunction.get("marNum"))){
                        limitNum = 5000 * (Integer.parseInt(orgFunction.get("marNum").toString()));
                    }
                }
                if("client".equals(ret.get("type").toString())){
                    if(null!=orgFunction && !StringUtils.isEmpty(orgFunction.get("cusNum"))){
                        limitNum = 5000 * (Integer.parseInt(orgFunction.get("cusNum").toString()));
                    }
                }

                if(limitNum != 0 && customerCount>limitNum){
                    customerCount = limitNum;
                }

                String touchCounts = "0";
                Long touchCount = stringRedisTemplate.opsForSet().size(touchcountKey);
                if(null != touchCount && touchCount>0){
                    touchCounts = touchCount.toString();
                }
                tmpParam.put("orgId",ret.get("orgId").toString());
                tmpParam.put("dynamicContent","主动营销客户<span>"+customerCount.toString()+"</span>人，触达<span>"+touchCounts+"</span>人，开始自动激活<span>0</span>人");
                tmpParam.put("dynamicType","1");
                tmpParam.put("robotType",ret.get("type").toString());
                sysConfigService.saveRobotDynamic(tmpParam);

                stringRedisTemplate.opsForSet().remove(wxPushListKey, str);
            }else{
                throw GlobalException.build("请求微信矩阵失败");
            }
            System.out.println(postres);
            System.out.println(jsonObject.toJSONString());
        }
    }

    @RedisLock("SendWxMessage_SendMassMsg")
    @Scheduled(cron = "48 0/10 * * * ?")
    public void SendMassWxMsg() throws IOException, URISyntaxException {

        //取这个月最后时刻
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        Date expireDate = calendar.getTime();

        Calendar calendarToday = Calendar.getInstance();
        calendarToday.set(Calendar.HOUR_OF_DAY, 23);
        calendarToday.set(Calendar.MINUTE, 59);
        calendarToday.set(Calendar.SECOND, 59);
        Date today = calendarToday.getTime();


        Set<String> kfmembers = stringRedisTemplate.opsForSet().members(wxPushListKey);
        if(null != kfmembers && kfmembers.size()>0){
//            throw GlobalException.build("客服消息队列还未推送完");
            LOGGER.info("客服消息队列还未推送完");
            return;
        }

        //取所有群发消息的key值
        Set<String> keyList = stringRedisTemplate.keys("textMassMessageList_*");
        if(null != keyList && keyList.size()>0){
            for (String key :keyList) {
                Set<String> members = stringRedisTemplate.opsForSet().members(key);
                if(null == members || members.size()<2){
//                    LOGGER.info("群发消息至少要2个openid");
                    continue;
                }
                StringBuilder openidIds = new StringBuilder();
                String token = "";
                String val = "";
                for(String str:members){
                    Map ret = (Map) JSON.parse(str);
                    String robotType = ret.get("type").toString();
                    String openidKey = "monthLimit_"+robotType+"_"+ret.get("token").toString()+"_"+ret.get("openid").toString();
                    String monthTimes = stringRedisTemplate.opsForValue().get(openidKey)==null?"0":stringRedisTemplate.opsForValue().get(openidKey);

                    int massLimit = 0;
                    if("market".equals(robotType)){
                        String marketRobotLimit = sysConfigService.getSysConfByName(ret.get("orgId").toString(), "marketRobotLimit");
                        massLimit = Integer.parseInt(marketRobotLimit==null?"1":marketRobotLimit);
                    }
                    if("client".equals(robotType)){
                        String clientRobotLimit = sysConfigService.getSysConfByName(ret.get("orgId").toString(), "clientRobotLimit");
                        massLimit = Integer.parseInt(clientRobotLimit==null?"1":clientRobotLimit);
                    }

                    Map<String, String> massdata = new HashMap<>();
                    massdata.put("desc", "");
                    massdata.put("image", "");
                    massdata.put("articleId",ret.get("articleId").toString());
                    massdata.put("url",ret.get("url").toString());
                    massdata.put("title",ret.get("title").toString());
                    massdata.put("token",ret.get("token").toString());
                    massdata.put("openid",ret.get("openid").toString());
                    massdata.put("type","mass");


                    Map<String, String> tmpParam = new HashMap<>();
                    Integer customerCount = customerService.getCustomerCountByOrgId(ret.get("orgId").toString());

                    //获取机器人配置
                    Integer limitNum = 0;
                    Map<String, Object> orgFunction = customerService.getOrgFunctionOrgId((String)ret.get("orgId"));
                    if("market".equals(ret.get("type").toString())){
                        if(null!=orgFunction && !StringUtils.isEmpty(orgFunction.get("marNum"))){
                            limitNum = 5000 * (Integer.parseInt(orgFunction.get("marNum").toString()));
                        }
                    }
                    if("client".equals(ret.get("type").toString())){
                        if(null!=orgFunction && !StringUtils.isEmpty(orgFunction.get("cusNum"))){
                            limitNum = 5000 * (Integer.parseInt(orgFunction.get("cusNum").toString()));
                        }
                    }
                    if(limitNum != 0 && customerCount>limitNum){
                        customerCount = limitNum;
                    }

//                    if(customerCount>5000){
//                        customerCount = 5000;
//                    }

                    String touchcountKey = "touchcount_" + ret.get("orgId").toString()+ret.get("type").toString();//触达人数key
                    String activatecountKey = "activatecount_" + ret.get("orgId").toString()+ret.get("type").toString();//激活人数key
                    String alltouchcountKey = "alltouchcount_" + ret.get("orgId").toString()+ret.get("type").toString();//触达人数key
                    String allactivatecountKey = "allactivatecount_" + ret.get("orgId").toString()+ret.get("type").toString();//激活人数key
                    String lockValue = ret.get("token").toString()+ret.get("openid").toString();//用户唯一标识

                    if(Integer.parseInt(monthTimes)<massLimit){
                        if (openidIds.length() > 0) {
                            openidIds.append(",").append(ret.get("openid"));
                        } else {
                            openidIds.append(ret.get("openid"));
                        }
                        stringRedisTemplate.opsForValue().increment(openidKey, 1);
                        stringRedisTemplate.expireAt(openidKey,expireDate);

                        //触达人数+1
                        stringRedisTemplate.opsForSet().add(alltouchcountKey,lockValue);
                        stringRedisTemplate.opsForSet().add(touchcountKey,lockValue);
                        stringRedisTemplate.expireAt(touchcountKey,today);

                        massdata.put("status","1");
                    }else{
                        // TODO 进入激活策略
                        stringRedisTemplate.opsForSet().add(allactivatecountKey,lockValue);
                        stringRedisTemplate.opsForSet().add(activatecountKey,lockValue);
                        stringRedisTemplate.expireAt(activatecountKey,today);
                        massdata.put("status","0");
                        //队列里拿掉这条数据
                        stringRedisTemplate.opsForSet().remove(key,str);
                    }

                    /*添加动态*/
                    String touchCounts = "0";
                    String alltouchCounts = "0";
                    Long touchCount = stringRedisTemplate.opsForSet().size(touchcountKey);
                    if(null!=touchCount && touchCount>0){
                        touchCounts = touchCount.toString();
                    }
                    Long alltouchCount = stringRedisTemplate.opsForSet().size(alltouchcountKey);
                    String marketRobotTouchCount = sysConfigService.getSysConfByName(ret.get("orgId").toString(), ret.get("type").toString()+"RobotTouchCount");
                    if(null!=alltouchCount && alltouchCount>0){
                        alltouchCounts = alltouchCount.toString();
                    }else{
                        if(StringUtils.isEmpty(marketRobotTouchCount)){
                            alltouchCounts = "0";
                        }else{
                            alltouchCounts = marketRobotTouchCount;
                        }
                    }
                    Map<String, String> touchCountParam = new HashMap<>();
                    touchCountParam.put("orgId",ret.get("orgId").toString());
                    touchCountParam.put("value",alltouchCounts);
                    touchCountParam.put("desc","智能营销机器人触达次数");
                    touchCountParam.put("name",ret.get("type").toString()+"RobotTouchCount");
                    if(StringUtils.isEmpty(marketRobotTouchCount)){
                        sysConfigService.addSysConf(touchCountParam);
                    }else {
                        sysConfigService.updateSysConf(touchCountParam);
                    }


                    String activateCounts = "0";
                    String allactivateCounts = "0";
                    Long activateCount = stringRedisTemplate.opsForSet().size(activatecountKey);
                    if(null!=activateCount && activateCount>0){
                        activateCounts = activateCount.toString();
                    }
                    Long allactivateCount = stringRedisTemplate.opsForSet().size(allactivatecountKey);
                    String marketRobotActivateCount = sysConfigService.getSysConfByName(ret.get("orgId").toString(), ret.get("type").toString()+"RobotActivateCount");
                    if(null!=allactivateCount && allactivateCount>0){
                        allactivateCounts = allactivateCount.toString();
                    }else{
                        if(StringUtils.isEmpty(marketRobotActivateCount)){
                            allactivateCounts = "0";
                        }else{
                            allactivateCounts = marketRobotActivateCount;
                        }
                    }

                    Map<String, String> activateCountParam = new HashMap<>();
                    activateCountParam.put("orgId",ret.get("orgId").toString());
                    activateCountParam.put("value",allactivateCounts);
                    activateCountParam.put("desc","智能营销机器人激活次数");
                    activateCountParam.put("name",ret.get("type").toString()+"RobotActivateCount");
                    if(StringUtils.isEmpty(marketRobotActivateCount)){
                        sysConfigService.addSysConf(activateCountParam);
                    }else {
                        sysConfigService.updateSysConf(activateCountParam);
                    }

                    tmpParam.put("orgId",ret.get("orgId").toString());
                    tmpParam.put("dynamicContent","主动营销客户<span>"+customerCount.toString()+"</span>人，触达<span>"+touchCounts+"</span>人，开始自动激活<span>"+activateCounts+"</span>人");
                    tmpParam.put("dynamicType","1");
                    tmpParam.put("robotType",ret.get("type").toString());
                    sysConfigService.saveRobotDynamic(tmpParam);
                    /*添加动态*/

                    marketRobotService.savePushLog(massdata);
                    token = ret.get("token").toString();
                    val = "<a href='"+ret.get("url").toString()+"'>"+ret.get("title").toString()+"</a>";
                }
                if(!StringUtils.isEmpty(openidIds) && !StringUtils.isEmpty(token) && !StringUtils.isEmpty(val)){

                    String[] split = openidIds.toString().split(",");
                    if(split.length<2){
//                        LOGGER.info("群发消息至少要2个openids");
                        continue;
                    }

                    Map<String, String> pushdata = new HashMap<>();
                    pushdata.put("action", "sendTextMassMessage");
                    pushdata.put("openids", openidIds.toString());
                    pushdata.put("val", val);
                    pushdata.put("token", token);
                    Map<String, String> postParam = new HashMap<>();
                    postParam.put("Content-Type", "application/json;charset=UTF-8");
                    JSONObject jsonObject = (JSONObject) JSONArray.toJSON(pushdata);
                    Object postresJson = httpService.doPost(url,jsonObject.toJSONString(),postParam);
                    LOGGER.info(postresJson.toString());
                    stringRedisTemplate.delete(key);
                }
            }
        }
    }

}
